﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MinistryStandardPlatformWeb.Models;
using MinistryStandardPlatformEntity;
using MinistryStandardPlatformWeb.Controllers.RealTime;
using System.IO;
using System.Text;


namespace MinistryStandardPlatformWeb.Controllers.Reports
{
    [MenuAuthorized("41")]
    public class OilAnalysisController : Controller
    {
        //
        // GET: /OilAnalysis/
        //油量分析
        private MSPGpsDataContext context = new MSPGpsDataContext();
        private MSPDataContext context1 = new MSPDataContext();


        public ActionResult Index(string startTime, string endTime, string ingoreZeroSpeedData)
        {
            ViewBag.StartTime = startTime;
            ViewBag.EndTime = endTime;
            ViewBag.IngoreZeroSpeedData = ingoreZeroSpeedData;
            return View();
        }

        public ActionResult Data(string vehicles,string startTime, string endTime, string ingoreZeroSpeedData)
        {
            List<string> paramaters = new List<string>();

            var dataDetail = from b in context.GpsBasic
                             where b.simId == vehicles &&
                             string.Compare(b.recordtime, startTime) >= 0 &&
                             string.Compare(b.recordtime, endTime) <= 0
                             select b;
            if (ingoreZeroSpeedData == "1") //过滤0速度数据
            {
                dataDetail = from d in dataDetail
                             where d.speed!=null &&
                             Math.Abs((double)(d.speed)-0.0)>0.0000000001
                             select d;
                paramaters.Add("0.0");
                paramaters.Add("0.0000000001");

            }

            //查出每条gps数据
            var analysisData = from d in dataDetail
                               orderby d.recordtime
                               select new OilAnalysis()
                               {
                                   Time = d.recordtime,
                                   Oil = d.attachOil,
                                   Mileage = d.mileage==-1?d.gpsmileage:d.mileage,
                                   Speed = d.speed,
                                   longitude=d.longitudeoffset,
                                   latitude=d.latitudeoffset
                               };
            paramaters.Add(vehicles.ToVarcharSqlParam());
            paramaters.Add(startTime.ToVarcharSqlParam());
            paramaters.Add(endTime.ToVarcharSqlParam());
            paramaters.Add("-1");
            string dataJsonStr = RealTimeGet.getReportFromGeoBase(CommonFunctions.GetLoginUser().UserId, CommonFunctions.GetSQL(analysisData, paramaters), startTime, endTime, "0");
            List<OilAnalysis> oilAnalyList = CommonFunctions.JsonStrToObject<List<OilAnalysis>>(dataJsonStr);

            oilAnalyList = (from o in oilAnalyList
                            orderby o.Time
                            select o).ToList();


            InfoVehicle vehicle = (from v in context1.InfoVehicle
                                   where v.SIM == vehicles
                                   select v).SingleOrDefault();

            List<AddOil> everyAddOil=new List<AddOil>();
            List<AddOil> everyLeakOil = new List<AddOil>();
            //开始统计相对前次行驶的路程以及加油漏油的数据,并组装highcharts需要的油量、速度和里程数据
            string mileageData ="";
            string oilData ="";
            string speedData ="";
            string timeData="";
            if (oilAnalyList.Count > 0)
            {
                mileageData = oilAnalyList[0].Mileage.ToString();
                oilData = oilAnalyList[0].Oil.ToString();
                speedData = oilAnalyList[0].Speed.ToString();
                timeData = oilAnalyList[0].Time.ToString();
            }
            
            for (int i = 1; i < oilAnalyList.Count; i++)
            {
                //相对前次行驶路程
                //oilAnalyList[i].MoveDistance = oilAnalyList[i].Mileage - oilAnalyList[i - 1].Mileage;
                mileageData += ("," + oilAnalyList[i].Mileage);
                oilData += ("," + oilAnalyList[i].Oil);
                speedData += ("," + oilAnalyList[i].Speed);
                timeData += ("," + oilAnalyList[i].Time);

                //如果车辆的邮箱已经初始化，需要统计加油和漏油的情况
                if (vehicle.IsOilBoxInited && vehicle.OilBoxVolumn>0.1)
                {
                    if (oilAnalyList[i].Oil > oilAnalyList[i - 1].Oil) //在加油
                    {
                        everyAddOil.Add(new AddOil()
                        {
                            StartTime = oilAnalyList[i - 1].Time,
                            EndTime = oilAnalyList[i].Time,
                            StartOil = oilAnalyList[i - 1].Oil,
                            EndOil = oilAnalyList[i].Oil,
                            AddedOil = oilAnalyList[i].Oil - oilAnalyList[i - 1].Oil,
                            longitude = oilAnalyList[i - 1].longitude,
                            latitude = oilAnalyList[i-1].latitude
                        });
                    }
                    //如果两次数据之间油量下降超过整个油箱容积的5%，则判定为漏油，否则判定为行驶过程中的油箱震荡引起的变化
                    if ((oilAnalyList[i - 1].Oil - oilAnalyList[i].Oil) >= vehicle.OilBoxVolumn * 0.05)
                    {
                        everyLeakOil.Add(new AddOil()
                        {
                            StartTime = oilAnalyList[i - 1].Time,
                            EndTime = oilAnalyList[i].Time,
                            StartOil = oilAnalyList[i - 1].Oil,
                            EndOil = oilAnalyList[i].Oil,
                            AddedOil = oilAnalyList[i-1].Oil - oilAnalyList[i].Oil,
                            longitude = oilAnalyList[i - 1].longitude,
                            latitude = oilAnalyList[i-1].latitude
                        });
                    }
                }
            }

            //如果连续几次上传都在加油，则将这几次加油合并
            List<AddOil> mergedAddOil = new List<AddOil>();
            int index = 0;
            double? totalAddedOil = 0.0;
            while (index < everyAddOil.Count - 1)
            {
                int end = index;
                double? addedOil = everyAddOil[index].AddedOil;
                while (everyAddOil[end + 1].StartTime == everyAddOil[end].EndTime)
                {
                    end++;
                    addedOil += everyAddOil[end].AddedOil;
                }
                totalAddedOil += addedOil;
                mergedAddOil.Add(new AddOil()
                {
                    StartTime = everyAddOil[index].StartTime,
                    EndTime = everyAddOil[end].EndTime,
                    StartOil = everyAddOil[index].StartOil,
                    EndOil = everyAddOil[end].EndOil,
                    AddedOil = addedOil,
                    longitude = everyAddOil[index].longitude,
                    latitude = everyAddOil[index].latitude
                });

                index = end+1;
            }

            //如果连续几次上传都在漏油，则将这几次漏油合并
            List<AddOil> mergedLeakOil = new List<AddOil>();
            index = 0; 
            while (index < everyLeakOil.Count - 1)
            {
                int end = index;
                double? addedOil = everyLeakOil[index].AddedOil;
                while (everyLeakOil[end + 1].StartTime == everyLeakOil[end].EndTime)
                {
                    end++;
                    addedOil += everyAddOil[end].AddedOil;
                }
                mergedLeakOil.Add(new AddOil()
                {
                    StartTime = everyLeakOil[index].StartTime,
                    EndTime = everyLeakOil[end].EndTime,
                    StartOil = everyLeakOil[index].StartOil,
                    EndOil = everyLeakOil[end].EndOil,
                    AddedOil = addedOil,
                    longitude = everyLeakOil[index].longitude,
                    latitude = everyLeakOil[index].latitude
                });
                index = end + 1;
            }

            //如果合并后的加油数据的油量上升值不超过整个油箱容积的5%，则判定为油箱震荡，不能算做加油
            for (int i = mergedAddOil.Count - 1; i >= 0;i-- )
            {
                if (mergedAddOil[i].AddedOil < vehicle.OilBoxVolumn * 0.05)
                {
                    mergedAddOil.Remove(mergedAddOil[i]);
                }
            }

            MinistryStandardPlatformBusiness.DBService.DBHelperClient geoHelper = new MinistryStandardPlatformBusiness.DBService.DBHelperClient();
            foreach (AddOil item in mergedAddOil)
            {
                item.Location = geoHelper.GgpsTranslate2BaiduPoi(item.longitude.ToString(), item.latitude.ToString());
            }

            foreach (AddOil item in mergedLeakOil)
            {
                item.Location = geoHelper.GgpsTranslate2BaiduPoi(item.longitude.ToString(), item.latitude.ToString());
            }

            ViewBag.VehicleName = vehicle.VehicleId + "(" + vehicle.SIM + ")";
            ViewBag.IsOilBoxIntied = vehicle.IsOilBoxInited && (vehicle.OilBoxVolumn>0.1);
            DateTime dt1 = Convert.ToDateTime(startTime);
            DateTime dt2 = Convert.ToDateTime(endTime);
            TimeSpan dt = dt2 - dt1;
            ViewBag.StatisticsTime = dt.Days.ToString() + "天" + dt.Hours.ToString() + "小时" + dt.Minutes.ToString() + "分钟" + dt.Seconds.ToString() + "秒";
            if (oilAnalyList.Count > 0)
            {
                ViewBag.MoveDistance = oilAnalyList[oilAnalyList.Count - 1].Mileage - oilAnalyList[0].Mileage;
                ViewBag.TotalAddedOil = totalAddedOil.Value.ToString("f3");
                ViewBag.UsedOil = oilAnalyList[0].Oil - oilAnalyList[oilAnalyList.Count - 1].Oil + totalAddedOil;
            }
            if ((double?)ViewBag.MoveDistance != 0.0)
            {
                ViewBag.OilPer100Km = ((double?)ViewBag.UsedOil / (double?)ViewBag.MoveDistance / 100.0).ToString();
            }
            ViewBag.MileageData = mileageData;
            ViewBag.OilData = oilData;
            ViewBag.SpeedData=speedData;
            ViewBag.TimeData = timeData;
            ViewBag.TimeOil = oilAnalyList;
            ViewBag.AddOil = mergedAddOil;
            ViewBag.LeakOil = mergedLeakOil;
            return PartialView();
        }

    }
}
